package xin.nick.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import xin.nick.common.entity.LoginUser;
import xin.nick.common.entity.ResultCode;
import xin.nick.common.entity.UserGrantedAuthority;
import xin.nick.common.util.MyAssert;
import xin.nick.entity.SystemUser;
import xin.nick.manager.SystemUserManager;
import xin.nick.mapper.SystemUserMapper;
import xin.nick.service.IRoleService;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Nick
 * @since 2022/7/21/021
 */
@Component
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class MyUserDetailsServiceImpl implements UserDetailsService {


    @Autowired
    private SystemUserMapper systemUserMapper;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private SystemUserManager systemUserManager;

    /**
     * 因为security自身的设计原因，角色权限前面需要添加ROLE前缀
     */
    private static final String ROLE_PREFIX = "ROLE_";

    /**
     * 因为security自身的设计原因，我们在用户分组和角色权限，增加ROLE前缀
     *
     * @param role 角色
     * @return SimpleGrantedAuthority
     */
    private SimpleGrantedAuthority genSimpleGrantedAuthority(String role) {
        if (!role.startsWith(ROLE_PREFIX)) {
            role = ROLE_PREFIX + role;
        }
        return new SimpleGrantedAuthority(role);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 这里的用户名,我在数据库设置为account的
        // 所以后面获取用户信息,通过account来获取
        MyAssert.isTrue(StringUtils.hasLength(username), "account不可为空");
        log.info("用户开始登陆: {}", username);

        // 获取用户信息,封装成 UserDetails 对象
        LambdaQueryWrapper<SystemUser> systemUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        systemUserLambdaQueryWrapper.eq(SystemUser::getAccount, username);
        SystemUser systemUser = systemUserMapper.selectOne(systemUserLambdaQueryWrapper);
        MyAssert.notNull(systemUser, ResultCode.ACCOUNT_OR_PASSWORD_ERROR);
        String userPassword = systemUser.getPassword();
        Long userId = systemUser.getUserId();

        // 授权列表
        List<GrantedAuthority> authorityList = systemUserManager.getGrantedAuthorityListByUserId(userId);

        // 获取角色key
        List<String> roleKeyList = roleService.getRoleKeyListByUserId(userId);
        List<SimpleGrantedAuthority> roleAuthorityList = roleKeyList.parallelStream().filter(Objects::nonNull).map(key -> new SimpleGrantedAuthority(ROLE_PREFIX + key)).collect(Collectors.toList());
        authorityList.addAll(roleAuthorityList);
        authorityList.add(new UserGrantedAuthority(ROLE_PREFIX  + "ADMIN2"));

        // 返回 UserDetails 对象
        LoginUser loginUser = new LoginUser(username, userPassword, authorityList);
        loginUser.setUserId(systemUser.getUserId());
        loginUser.setNickname(systemUser.getUsername());
        return loginUser;
    }
}
